package cn.lili.modules.distribution.serviceimpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.constant.CommonConstant;
import cn.lili.modules.distribution.entity.dos.Distribution;
import cn.lili.modules.distribution.entity.dto.DistributionApplyDTO;
import cn.lili.modules.distribution.entity.dto.DistributionSearchParams;
import cn.lili.modules.distribution.entity.enums.DistributionStatusEnum;
import cn.lili.modules.distribution.entity.vos.DistributionVO;
import cn.lili.modules.distribution.entity.vos.QualificationCheckVO;
import cn.lili.modules.distribution.mapper.DistributionMapper;
import cn.lili.modules.distribution.service.DistributionService;
import cn.lili.modules.member.client.UnionClient;
import cn.lili.modules.member.client.UnionMemberClient;
import cn.lili.modules.member.client.UserClient;
import cn.lili.modules.member.entity.dos.Union;
import cn.lili.modules.member.entity.dos.UnionMember;
import cn.lili.modules.member.entity.dos.User;
import cn.lili.modules.member.entity.vo.NumberOfOwners;
import cn.lili.modules.operationcenter.client.OperationCenterClient;
import cn.lili.modules.operationcenter.entity.dos.OperationCenter;
import cn.lili.modules.order.order.client.OrderClient;
import cn.lili.modules.order.order.client.OrderItemClient;
import cn.lili.modules.order.order.client.RankingDistributionClient;
import cn.lili.modules.order.order.entity.dos.OrderFlow;
import cn.lili.modules.order.order.entity.dto.OrderItemFlowSearchParams;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.ProfitSharingStatusEnum;
import cn.lili.modules.order.order.entity.vo.OrderItemFlowUserVO;
import cn.lili.modules.order.order.entity.vo.OrderItemViewVO;
import cn.lili.modules.payment.client.LiUserPointsWithdrawClient;
import cn.lili.modules.payment.entity.dos.LiUserPointsWithdraw;
import cn.lili.modules.system.client.DictionaryClient;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.constants.DictConstant;
import cn.lili.modules.system.entity.dos.Dictionary;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.DistributionSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import com.alibaba.fastjson.JSONObject;
import com.api.PayApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 分销员接口实现
 *
 * @author pikachu
 * @since 2020-03-14 23:04:56
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DistributionServiceImpl extends ServiceImpl<DistributionMapper, Distribution> implements DistributionService {

    /**
     * 会员
     */
    private final UserClient userClient;
    /**
     * 订单
     */
    private final OrderClient orderClient;
    /**
     * 缓存
     */
    private final Cache cache;
    /**
     * 设置
     */
    private final SettingClient serviceClient;

    private final OrderItemClient orderItemClient;

    private final LiUserPointsWithdrawClient pointsWithdrawClient;

    private final PayApi payApi;

    private final RankingDistributionClient rankingDistributionClient;

    private final SettingClient settingClient;

    private final DictionaryClient dictionaryClient;

    private final UnionMemberClient unionMemberClient;

    private final UnionClient unionClient;

    private final OperationCenterClient operationCenterClient;

    public Page<Distribution> queryDistributionPage(DistributionSearchParams param, PageVO page) {
        LambdaQueryWrapper<Distribution> query = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(param.getDistributionStatus())) {
            query.eq(Distribution::getDistributionStatus, param.getDistributionStatus());
        }
        if (StringUtils.isNotEmpty(param.getMemberName())) {
            query.like(Distribution::getMemberName, param.getMemberName());
        }
        if (StringUtils.isNotEmpty(param.getParentId())) {
            query.and(wrapper -> wrapper.likeRight(Distribution::getParentId, param.getParentId())
                    .or()
                    .likeRight(Distribution::getParentUsername, param.getParentId()));
        }
        query.orderByDesc(Distribution::getCreateTime).orderByDesc(Distribution::getId);
        //分页获取店长
        return baseMapper.selectPage(new Page<>(page.getPageNumber(), page.getPageSize()), query);
    }

    public Page<Distribution> queryDistributionPage1(DistributionSearchParams param, PageVO page) {
        //分页获取店长
        return baseMapper.queryDistributionPage1(new Page<>(page.getPageNumber(), page.getPageSize()), param);
    }

    @Override
    public Page<Distribution> distributionPage(DistributionSearchParams param, PageVO page) {
        //分页获取店长
        Page<Distribution> pageR = this.queryDistributionPage(param, page);
        if (CollUtil.isNotEmpty(pageR.getRecords())) {
            List<String> memberIds = pageR.getRecords().stream().map(e -> e.getMemberId()).collect(Collectors.toList());
            //统计店长下级人数
            Map<String, Integer> map = userClient.selectUserChildCountByUserIds(memberIds);
            // TODO: 2024/1/7 这里可能涉及使用大量内存，后期优化可考虑分段 list查询
            //获取li_user表所有下级id
            Map<String, List<String>> mapChildIds = userClient.selectChildUserIdsByMemberIds(memberIds);
            Map<String, OrderFlow> disUserLowerPrice = null;
            if (CollUtil.isNotEmpty(mapChildIds)) {
                //3.直销业绩：根据下级用户ID，统计li_order_flow订单流水表表flow_price字段（已结算）
                disUserLowerPrice = orderClient.selectSubUserFlowPrice(mapChildIds);
            }
            for (Distribution dis : pageR.getRecords()) {
                //赋值下级人数
                if (CollUtil.isNotEmpty(map)) {
                    dis.setChildCount(map.get(dis.getMemberId()) != null ? map.get(dis.getMemberId()) : 0);
                }
                //赋值-直销业绩,佣金收益
                if (CollUtil.isNotEmpty(disUserLowerPrice)) {
                    //直销业绩
                    dis.setLowerTotalPrice(disUserLowerPrice.get(dis.getMemberId()) != null ? disUserLowerPrice.get(dis.getMemberId()).getFlowPrice() : 0.0);
                    //佣金收益: 店主直推佣金 + 店主间推佣金  之和
                    List<Distribution> childDisList = this.selectDisLowerAndLowerSubComissByParentId(dis.getMemberId(), null, null);
                    if (CollUtil.isNotEmpty(childDisList)) {
                        double sum = childDisList.stream()
                                .mapToDouble(Distribution::getEarnings)
                                .sum();
                        dis.setTotalCommiss(sum);
                    }
                }
            }
        }
        return pageR;
    }


    /**
     * 分页获取-分销员/店主列表
     *
     * @param param
     * @param page
     * @return
     */
    @Override
    public Page<Distribution> distributionPage1(DistributionSearchParams param, PageVO page) {
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        //1,查询店主列表
        Page<Distribution> pageR = this.queryDistributionPage1(param, page);
        if (CollUtil.isNotEmpty(pageR.getRecords())) {
            //根据店主用户id查询直推业绩和佣金收益
            List<String> memberIds = pageR.getRecords().stream().map(e -> e.getMemberId()).collect(Collectors.toList());
            //统计店长下级人数
            Map<String, Integer> childCountMap = userClient.selectUserChildCountByUserIds(memberIds);
            //查询直推金额和收益佣金
            List<OrderItemViewVO> viewVo = orderItemClient.getDistributionFlowPriceAndComissTotal(memberIds);

            for (Distribution dis : pageR.getRecords()) {
                //赋值下级人数
                if (CollUtil.isNotEmpty(childCountMap)) {
                    dis.setChildCount(childCountMap.get(dis.getMemberId()) != null ? childCountMap.get(dis.getMemberId()) : 0);
                }
                if (CollUtil.isNotEmpty(viewVo)) {
                    for (OrderItemViewVO vo : viewVo) {
                        //赋值直销业绩
                        if (vo.getLowerCommissId() != null && vo.getLowerCommissId().equals(dis.getMemberId())) {
                            dis.setLowerTotalPrice(dis.getLowerTotalPrice() + vo.getFlowPrice());
                            dis.setTotalCommiss(dis.getTotalCommiss() + vo.getLowerCommiss() + vo.getLowerSubCommiss());
                        }
                        //赋值 收益佣金
                        if (vo.getLowerSubCommissId() != null && vo.getLowerSubCommissId().equals(dis.getMemberId())) {
                            dis.setTotalCommiss(dis.getTotalCommiss() + vo.getLowerCommiss() + vo.getLowerSubCommiss());
                        }
                    }
                }
                //保留两位
                dis.setTotalCommiss(dis.getTotalCommiss() != null ? Double.valueOf(decimalFormat.format(dis.getTotalCommiss())) : 0.0);
                //给parentId反回昵称字段,展示用
                dis.setParentId(StringUtils.isNotEmpty(dis.getParentUsername()) ? dis.getParentUsername() : "");
            }
        } else {
            pageR = new Page<>();
        }
        return pageR;
    }

    @Override
    public List<Distribution> selectDisLowerAndLowerSubComissByParentId(String memberId, String flowTime, String nickName) {
        List<Distribution> userFlowDTOS = baseMapper.getLowerAndLowerComissSubByParentId(memberId, null, ProfitSharingStatusEnum.FINISHED.name(), null);
        return userFlowDTOS;
    }

    @Override
    public Distribution getDistribution() {
        if (null != UserContext.getCurrentUser()) {
            return this.getOne(new LambdaQueryWrapper<Distribution>().eq(Distribution::getMemberId, Objects.requireNonNull(UserContext.getCurrentUser()).getId()).orderByDesc(Distribution::getCreateTime).last("limit 1"));
        }
        return null;
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public Distribution applyDistribution(DistributionApplyDTO distributionApplyDTO) {
        //校验是否够资格申请
        if (!isApplyDistribution()) {
            Setting setting = settingClient.get(SettingEnum.DISTRIBUTION_SETTING.name());
            DistributionSetting distributionSetting = JSONUtil.toBean(setting.getSettingValue(), DistributionSetting.class);
            throw new ServiceException("您还未达到申请，条件（消费满 " + distributionSetting.getShopkeeper() + "）请继续努力");
        }
        String memberId = Objects.requireNonNull(UserContext.getCurrentUser()).getId();
        //检查分销开关
        checkDistributionSetting();

        //判断用户是否申请过分销
        Distribution distribution = getDistribution();

        //如果分销员非空并未审核则提示用户请等待，如果分销员为拒绝状态则重新提交申请
        if (Optional.ofNullable(distribution).isPresent()) {
            if (distribution.getDistributionStatus().equals(DistributionStatusEnum.APPLY.name())) {
                throw new ServiceException(ResultCode.DISTRIBUTION_IS_APPLY);
            } else if (distribution.getDistributionStatus().equals(DistributionStatusEnum.REFUSE.name())) {
                distribution.setDistributionStatus(DistributionStatusEnum.APPLY.name());
                BeanUtil.copyProperties(distributionApplyDTO, distribution);
                this.updateById(distribution);
                return distribution;
            }
        }
        //如果未申请分销员则新增进行申请
        //获取当前登录用户
        User member = userClient.getById(memberId);
        //新建分销员
        distribution = new Distribution(member.getId(), member.getNickName(), distributionApplyDTO);
        //查询上级信息
        if (StringUtils.isNotEmpty(member.getParentId())) {
            User parentUser = userClient.getById(member.getParentId());
            distribution.setParentId(parentUser != null ? parentUser.getId() : null);
            distribution.setParentUsername(parentUser != null ? parentUser.getUsername() : null);
        }
        distribution.setNickName(member.getNickName());
        //添加分销员
        this.save(distribution);

        return distribution;
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public boolean audit(String id, String status) {

        //检查分销开关
        checkDistributionSetting();

        //根据id获取分销员
        Distribution distribution = this.getById(id);
        if (Optional.ofNullable(distribution).isPresent()) {
            if (status.equals(DistributionStatusEnum.PASS.name())) {
                distribution.setDistributionStatus(DistributionStatusEnum.PASS.name());
                rankingDistributionClient.save(distribution);
                //这里维护User表里的是否是店长标识
                User u = userClient.getById(distribution.getMemberId());
                u.setIsDistribution(Boolean.TRUE);
                userClient.updateById(u);
                //更新店长上级信息
                distribution.setParentId(StringUtils.isNotEmpty(u.getParentId())?u.getParentId():"");
                distribution.setParentUsername(StringUtils.isNotEmpty(u.getParentUsername()) ? u.getParentUsername() : "");
            } else {
                distribution.setDistributionStatus(DistributionStatusEnum.REFUSE.name());
            }
            distribution.setAuditTime(new Date());
            return this.updateById(distribution);
        }
        return false;
    }

    @Override
    public Page<OrderItemFlowUserVO> distributionOrder(Integer pageNumber, Integer pageSize) {

        OrderItemFlowSearchParams searchParam = new OrderItemFlowSearchParams();
        searchParam.setAfterSaleStatus(OrderItemAfterSaleStatusEnum.EXPIRED.name());
        searchParam.setDistributionId(UserContext.getCurrentUser().getId());
        searchParam.setPageSize(pageSize);
        searchParam.setPageNumber(pageNumber);
        searchParam.setSort("createTime");

        Page<OrderItemFlowUserVO> orderSimpleVOPage = orderItemClient.getOrderFlowUserVOByCondition(searchParam);

        return orderSimpleVOPage;
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public boolean retreat(String id) {
        //检查分销开关
        checkDistributionSetting();

        //根据id获取分销员
        Distribution distribution = this.getById(id);
        if (Optional.ofNullable(distribution).isPresent()) {
            distribution.setDistributionStatus(DistributionStatusEnum.RETREAT.name());
            //清除自己的上级
            distribution.setParentId("");
            distribution.setParentUsername("");
            if (this.updateById(distribution)) {
                //清除店长里的上级关系
                LambdaQueryWrapper<Distribution> query = new LambdaQueryWrapper<>();
                query.eq(Distribution::getParentId, distribution.getMemberId());
                query.select(Distribution::getId);
                List<Distribution> subDis = this.list(query);
                //清除店长里的本人下级店长关系
                if (CollUtil.isNotEmpty(subDis)) {
                    LambdaUpdateWrapper<Distribution> updateWrapper = new LambdaUpdateWrapper();
                    updateWrapper.in(Distribution::getId, subDis.stream().map(Distribution::getId).collect(Collectors.toList()));
                    updateWrapper.set(Distribution::getParentId, "");
                    updateWrapper.set(Distribution::getParentUsername, "");
                    this.update(updateWrapper);
                }
                //清除用户表邀请人id
                User u = new User();
                u.setParentId(distribution.getMemberId());
                userClient.removeChildUserRelationship(u);
                //店主排名的逻辑--这里增加清退店长排名的操作
                rankingDistributionClient.removeRankingDistribution(distribution);
                return true;
            }
        }
        return false;
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public boolean resume(String id) {

        //检查分销开关
        checkDistributionSetting();

        //根据id获取分销员
        Distribution distribution = this.getById(id);
        if (Optional.ofNullable(distribution).isPresent()) {
            distribution.setDistributionStatus(DistributionStatusEnum.PASS.name());
            return this.updateById(distribution);
        }
        return false;
    }

    @Override
    public void bindingDistribution(String distributionId) {

        //判断用户是否登录，未登录不能进行绑定
        if (UserContext.getCurrentUser() == null) {
            throw new ServiceException(ResultCode.USER_NOT_LOGIN);
        }
        //储存分销关系时间
        Distribution distribution = this.getById(distributionId);
        if (distribution != null) {
            Setting setting = serviceClient.get(SettingEnum.DISTRIBUTION_SETTING.name());
            DistributionSetting distributionSetting = JSONUtil.toBean(setting.getSettingValue(), DistributionSetting.class);
            cache.put(CachePrefix.DISTRIBUTION.getPrefix() + UserContext.getCurrentUser().getId(), distribution, distributionSetting.getDistributionDay().longValue(), TimeUnit.DAYS);
        }

    }

    /**
     * 检查分销设置开关
     */
    @Override
    public void checkDistributionSetting() {
        //获取分销是否开启
        log.info("同步分销商品,进入 检查分销设置开关 方法");
        Setting setting = serviceClient.get(SettingEnum.DISTRIBUTION_SETTING.name());
        log.info("同步分销商品,serviceClient.get()方法结果:{}", JSONObject.toJSONString(setting));
        DistributionSetting distributionSetting = JSONUtil.toBean(setting.getSettingValue(), DistributionSetting.class);
        if (Boolean.FALSE.equals(distributionSetting.getIsOpen())) {
            log.info("同步分销商品,检查分销设置开关-->关闭");
            throw new ServiceException(ResultCode.DISTRIBUTION_CLOSE);
        }
        log.info("同步分销商品,结束 检查分销设置开关 方法");
    }

    @Override
    public void updateDistributionAmount() {
        //获取分销是否开启
        Setting setting = serviceClient.get(SettingEnum.DISTRIBUTION_SETTING.name());
        DistributionSetting distributionSetting = JSONUtil.toBean(setting.getSettingValue(), DistributionSetting.class);
        if (Boolean.TRUE.equals(distributionSetting.getIsOpen())) {
            //获取分销员
            List<Distribution> distributions = this.list(new LambdaQueryWrapper<Distribution>().eq(Distribution::getDistributionStatus, DistributionStatusEnum.PASS.name()));
            //更新分销员的分销金额
            distributions.forEach(distribution -> {
                OrderItemFlowSearchParams searchParam = new OrderItemFlowSearchParams();
                searchParam.setAfterSaleStatus(OrderItemAfterSaleStatusEnum.EXPIRED.name());
                searchParam.setDistributionId(distribution.getMemberId());
                // 获取分销员的总分销金额
                long amount = orderItemClient.amountOderFlowUserVOByCondition(searchParam);
                System.out.println("分销结算接口");
                System.out.println(amount);
                if (amount > 0) {
                    LambdaUpdateWrapper<Distribution> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.set(Distribution::getRebateTotal, amount);
                    updateWrapper.eq(Distribution::getId, distribution.getId());
                    this.update(updateWrapper);
                }
            });
        }
    }


    /**
     * 分润提现
     *
     * @param distributionSearchParams 分润提现
     * @return 分润提现
     */
    @Override
    @ShardingTransactionType(TransactionType.BASE)
    public ResultMessage<Object> withdraw(DistributionSearchParams distributionSearchParams) {
        if (!StringUtils.isNumeric(distributionSearchParams.getMoney())) {
            return ResultUtil.error(500, "提现金额请输入数字");
        }
        if (distributionSearchParams.getMoney() == null) {
            return ResultUtil.error(500, "提现金额为空");
        }
        AuthUser currentUser = UserContext.getCurrentUser();
        if (currentUser == null) {
            return ResultUtil.error(500, "登录已过期");
        }
        //添加提现记录
        Distribution distribution = super.getOne(new LambdaQueryWrapper<Distribution>().eq(Distribution::getMemberId, currentUser.getId()).orderByDesc(Distribution::getCreateTime).last("limit 1"));
        if (distribution == null) {
            return ResultUtil.error(500, "未找到用户钱包");
        }
        if (distribution.getRebateTotal() < Integer.parseInt(distributionSearchParams.getMoney())) {
            return ResultUtil.error(500, "积分余额不够。当前积分余额:" + distribution.getRebateTotal() + ",提现积分:" + distributionSearchParams.getMoney());
        }
        String remark = currentUser.getNickName() + "提现:" + distributionSearchParams.getMoney();
        LiUserPointsWithdraw pointsWithdraw = new LiUserPointsWithdraw();
        pointsWithdraw.setCreateBy(currentUser.getId());
        pointsWithdraw.setCreateTime(new Date());
        pointsWithdraw.setMemberId(Long.valueOf(currentUser.getExtendId()));
        pointsWithdraw.setMemberName(currentUser.getNickName());
        pointsWithdraw.setRemark(remark);
        pointsWithdraw.setBeforePoint(String.valueOf(distribution.getRebateTotal()));
        pointsWithdraw.setMoney(String.valueOf(distributionSearchParams.getMoney()));
        pointsWithdraw.setAfterPoint(String.valueOf(CurrencyUtil.sub(distribution.getRebateTotal(), Double.parseDouble(distributionSearchParams.getMoney()))));
        pointsWithdraw.setWithdrawType(CommonConstant.WITHDRAW_TYPE_2);
        pointsWithdraw.setAuditStatus(CommonConstant.AUDIT_STATUS_00);
        LiUserPointsWithdraw withdraw = pointsWithdrawClient.saveWithdraw(pointsWithdraw);
        return ResultUtil.data(true);
    }


    /**
     * 提现审核
     *
     * @param id          提现单id
     * @param auditStatus 审核状态： 1通过，2驳回
     * @return 审核结果
     */
    @Override
    @ShardingTransactionType(TransactionType.BASE)
    public ResultMessage<Object> auditWithdraw(String id, String auditStatus, String remark) {
        AuthUser currentUser = UserContext.getCurrentUser();
        if (currentUser == null) {
            return ResultUtil.error(500, "登录已过期");
        }
        if (!StringUtils.isNumeric(auditStatus) || Integer.valueOf(auditStatus) > 2) {
            throw new ServiceException("审核状态异常");
        }
        if (CommonConstant.AUDIT_STATUS_02.equals(Integer.valueOf(auditStatus)) && StringUtils.isEmpty(remark)) {
            throw new ServiceException("驳回备注为空");
        }
        //获取数据
        LiUserPointsWithdraw pointsWithdraw = pointsWithdrawClient.getById(id);
        if (Integer.parseInt(pointsWithdraw.getAfterPoint()) < 0) {
            throw new ServiceException("资金异常");
        }

        pointsWithdraw.setAuditStatus(Integer.valueOf(auditStatus));
        pointsWithdraw.setRemark(remark);
        pointsWithdraw.setAuditBy(currentUser.getId());
        pointsWithdraw.setAuditUserName(currentUser.getNickName());
        pointsWithdraw.setAuditTime(new Date());
        pointsWithdrawClient.updateById(pointsWithdraw);

        //修改正在待审核的数据的提现前，以及提现后的数据。


        Distribution distribution = super.getOne(new LambdaQueryWrapper<Distribution>().eq(Distribution::getMemberId, currentUser.getId()).orderByDesc(Distribution::getCreateTime).last("limit 1"));
        if (distribution == null) {
            return ResultUtil.error(500, "未找到用户钱包");
        }
        if (distribution.getRebateTotal() < Integer.parseInt(pointsWithdraw.getMoney())) {
            return ResultUtil.error(500, "积分余额不够。当前积分余额:" + distribution.getRebateTotal() + ",提现积分:" + pointsWithdraw.getMoney());
        }
        //变更分润的余额
        distribution.setRebateTotal(Double.valueOf(pointsWithdraw.getAfterPoint()));
        super.updateById(distribution);
        //提现
        if (StringUtils.isEmpty(currentUser.getOpenId())) {
            throw new ServiceException("当前用户未绑定飞语");
        }
        boolean payment = payApi.gMoneyPayment(currentUser.getOpenId(), remark, 0, Integer.parseInt(pointsWithdraw.getMoney()), 2, 3);
        if (!payment) {
            throw new ServiceException("服务异常，用户提现失败");
        }
        return ResultUtil.data(payment);
    }

    /**
     * 能否申请成为分销员
     *
     * @return true / false
     */
    @Override
    public Boolean isApplyDistribution() {
        if (StringUtils.isEmpty(UserContext.getCurrentId())) {
            log.info("未登录，请先获取后，获取是否分销员状态");
            return false;
        }
//        Distribution distribution = this.getDistribution();
        //已经成为店主，不能再去申请
//        if (distribution != null && DistributionStatusEnum.PASS.name().equals(distribution.getDistributionStatus())) {
//            return false;
//        }
        //在商城消费是否满
        Double money = orderClient.getShopkeeperMoneyByUid(UserContext.getCurrentId());
        String userId = UserContext.getCurrentUser().getId();
        List<Dictionary> distributionList = dictionaryClient.getListByCode(DictConstant.DISTRIBUTION_NAME);
        if (CollectionUtil.isNotEmpty(distributionList)) {
            for (Dictionary dictionary : distributionList) {
                String[] descriptionArr = dictionary.getDescription().split(",");
                String[] valueNameArr = dictionary.getValueName().split(",");
                for (String description : descriptionArr) {
                    if (userId.equals(description)) {
                        return true;
                    }
                }
                for (String valueName : valueNameArr) {
                    if (userId.equals(valueName)) {
                        return true;
                    }
                }
            }
        }

        Setting setting = settingClient.get(SettingEnum.DISTRIBUTION_SETTING.name());
        DistributionSetting distributionSetting = JSONUtil.toBean(setting.getSettingValue(), DistributionSetting.class);
        return StringUtils.isNotEmpty(distributionSetting.getShopkeeper()) && Double.parseDouble(distributionSetting.getShopkeeper()) <= money;
    }


    /**
     * 根据Id查询店主/分销员信息
     *
     * @param id
     * @return
     */
    @Override
    public Distribution selectDistributionById(String id) {
        LambdaQueryWrapper<Distribution> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Distribution::getId, id);
        Distribution dis = baseMapper.selectOne(queryWrapper);
        if (null != dis) {
            User user = userClient.getById(dis.getMemberId());
            //头像
            dis.setFace(user != null && StringUtils.isNotEmpty(user.getFace()) ? user.getFace() : "");
            //查询订单金额
            Double totalOrderPrice = orderClient.getMoneyByUid(dis.getMemberId());
            dis.setTotalOrderPrice(totalOrderPrice);
            return dis;
        }
        return new Distribution();
    }

    /**
     * 获取城主资格校验
     */
    @Override
    public QualificationCheckVO qualificationCheck() {
        QualificationCheckVO result = new QualificationCheckVO();
        result.setCheck(false);
        result.setTotal(0L);
        result.setCurrentTotal(0L);
        //所需下级人数
        Setting setting = settingClient.get(SettingEnum.DISTRIBUTION_SETTING.name());
        DistributionSetting distributionSetting = JSONUtil.toBean(setting.getSettingValue(), DistributionSetting.class);
        if (distributionSetting != null && StringUtils.isNotEmpty(distributionSetting.getCastellan())) {
            result.setTotal(Long.valueOf(distributionSetting.getCastellan()));
        }
        Distribution distribution = this.getDistribution();
        if (distribution == null) {
            return result;
        }
        //当前下级人数
        LambdaQueryWrapper<Distribution> distributionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        distributionLambdaQueryWrapper.eq(Distribution::getParentId, UserContext.getCurrentId());
        distributionLambdaQueryWrapper.eq(Distribution::getDistributionStatus, DistributionStatusEnum.PASS.name());
        long count = super.count(distributionLambdaQueryWrapper);
        result.setCurrentTotal(count);
        //资格条件是否，达成
        if (result.getTotal() > 0 && result.getCurrentTotal() >= result.getTotal()) {
            result.setCheck(true);
        }
        return result;
    }

    /**
     * 搜索店主
     *
     * @param keyword
     * @return
     */
    @Override
    public List<Distribution> getListByName(String keyword) {
        LambdaQueryWrapper<Distribution> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Distribution::getDistributionStatus,DistributionStatusEnum.PASS.name());
        queryWrapper.and(tmp -> tmp.likeRight(Distribution::getId, keyword).or().likeRight(Distribution::getMemberName, keyword));

        queryWrapper.last("limit 10");
        return this.list(queryWrapper);
    }

    /**
     * 根据userid查询已通过的分销员
     * @param memberId
     * @return
     */
    @Override
    public Distribution selectDistributionByMemberId(String memberId) {
        LambdaQueryWrapper<Distribution> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Distribution::getDistributionStatus, DistributionStatusEnum.PASS.name());
        queryWrapper.eq(Distribution::getMemberId, memberId);
        queryWrapper.last("limit 1");
        return baseMapper.selectOne(queryWrapper);
    }

    /**
     * 运营中心 --》 店主列表
     */
    @Override
    public IPage<DistributionVO> shopkeeperPage(DistributionVO distributionVO) {
        Page<DistributionVO> result = new Page<>();
        LambdaQueryWrapper<Distribution> queryWrapper = this.createQueryWrapper(distributionVO);
        Page<Distribution> distributionPage = super.page(new Page<>(distributionVO.getPageNumber(), distributionVO.getPageSize()), queryWrapper);
        if (CollectionUtil.isEmpty(distributionPage.getRecords())) {
            return result;
        }
        List<Distribution> distributionList = distributionPage.getRecords();
        //将其类型转换，并计算数据
        List<String> idList = distributionList.stream().map(Distribution::getMemberId).toList();
        List<Union> unionList = unionClient.getListByChairmanIdList(idList);
        List<UnionMember> unionMemberList = unionMemberClient.getUnionMemberByIdList(idList);
        //根据店主用户id查询直推业绩和佣金收益
        List<String> memberIds = distributionList.stream().map(Distribution::getMemberId).collect(Collectors.toList());
        //统计店长下级人数
        Map<String, Integer> childCountMap = userClient.selectUserChildCountByUserIds(memberIds);
        //用户信息列表
        List<User> userList = userClient.selectUserListByIds(memberIds);

        //查询直推金额和收益佣金
        List<OrderItemViewVO> totalPerformance = orderItemClient.getDistributionFlowPriceAndComissTotalDistribution(memberIds);
        List<OrderItemViewVO> monthlyPerformance = orderItemClient.getDistributionFlowPriceAndComissTotalCurrentMonth(memberIds);
        List<OrderItemViewVO> lastMonthResults = orderItemClient.getDistributionFlowPriceAndComissTotalLastMonth(memberIds);
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        List<DistributionVO> resultList = new ArrayList<>();
        for (Distribution distribution : distributionList) {
            DistributionVO vo = cn.hutool.core.bean.BeanUtil.toBean(distribution, DistributionVO.class);
            vo.setCurrentMonthResults(0D);
            vo.setLastMonthResults(0D);
            vo.setTotalCommiss(0D);
            if (CollectionUtil.isNotEmpty(userList)) {
                for (User user : userList) {
                    if (user.getId().equals(distribution.getMemberId())) {
                        vo.setFyAccount(user.getAccount());
                        vo.setFyName(user.getFyName());
                    }
                }
            }

            List<Union> list = unionList.stream().filter(union -> union.getChairmanId().equals(distribution.getMemberId())).toList();
            if (!list.isEmpty()) {
                vo.setUnionName(list.get(0).getUnionName());
                vo.setAddTime(list.get(0).getCreateTime());
            }else {
                List<UnionMember> unionMembers = unionMemberList.stream().filter(unionMember -> unionMember.getMemberId().equals(distribution.getMemberId())).toList();
                if (!unionMembers.isEmpty()) {
                    Union union = unionClient.getById(unionMembers.get(0).getUnionId());
                    if (null != union) {
                        vo.setUnionName(union.getUnionName());
                        vo.setAddTime(unionMembers.get(0).getJoinTime());
                    }
                }
            }

            /*if (CollectionUtil.isNotEmpty(unionMemberList)) {
                for (Distribution distribution1 : distributionList) {
                    for (UnionMember unionMember : unionMemberList) {
                        if (unionMember.getMemberId().equals(distribution1.getMemberId())) {
                            vo.setAddTime(unionMember.getJoinTime());
                            for (Union union : unionList) {
                                if (union.getId().equals(unionMember.getUnionId())) {
                                    vo.setUnionName(union.getUnionName());
                                }
                            }
                        }
                    }
                }
            }*/

            //赋值下级人数
            if (CollUtil.isNotEmpty(childCountMap)) {
                vo.setChildCount(childCountMap.get(vo.getMemberId()) != null ? childCountMap.get(vo.getMemberId()) : 0);
            }
            if (CollUtil.isNotEmpty(totalPerformance)) {
                for (OrderItemViewVO orderItemViewVO : totalPerformance) {
                    //赋值总业绩
                    if (orderItemViewVO.getLowerCommissId() != null && orderItemViewVO.getLowerCommissId().equals(vo.getMemberId())) {
                        vo.setTotalCommiss(vo.getTotalCommiss() + orderItemViewVO.getFlowPrice());
                    }
                }
            }
            if (CollUtil.isNotEmpty(monthlyPerformance)) {
                for (OrderItemViewVO orderItemViewVO : monthlyPerformance) {
                    //赋值当月业绩
                    if (orderItemViewVO.getLowerCommissId() != null && orderItemViewVO.getLowerCommissId().equals(vo.getMemberId())) {
                        vo.setCurrentMonthResults(vo.getCurrentMonthResults() + orderItemViewVO.getFlowPrice());
                    }
                }
            }
            if (CollUtil.isNotEmpty(lastMonthResults)) {
                for (OrderItemViewVO orderItemViewVO : lastMonthResults) {
                    //赋值上月业绩
                    if (orderItemViewVO.getLowerCommissId() != null && orderItemViewVO.getLowerCommissId().equals(vo.getMemberId())) {
                        vo.setLastMonthResults(vo.getLastMonthResults() + orderItemViewVO.getFlowPrice());
                    }
                }
            }
            //保留两位
            vo.setTotalCommiss(vo.getTotalCommiss() != null ? Double.parseDouble(decimalFormat.format(vo.getTotalCommiss())) : 0.0);
            //给parentId反回昵称字段,展示用
            vo.setParentId(StringUtils.isNotEmpty(vo.getParentUsername()) ? vo.getParentUsername() : "");
            resultList.add(vo);
        }

        BeanUtils.copyProperties(distributionPage, result);
        result.setRecords(resultList);
        return result;
    }

    @Override
    public LambdaQueryWrapper<Distribution> createQueryWrapper(DistributionVO distributionVO) {
        LambdaQueryWrapper<Distribution> distributionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        AuthUser authUser = UserContext.getCurrentUser();
        if (authUser == null) {
            throw new ServiceException("请先登录后重试");
        }
        //获取运行中心省份id
        OperationCenter operationCenter = operationCenterClient.getOperationCenter(authUser.getId());
        if (operationCenter == null) {
            throw new ServiceException("未获取到，运营中心信息");
        }
        //获取省份下的工会
        List<Union> unionList =  unionClient.getListByFiled("province_id", operationCenter.getProvinceId());
        if (CollectionUtil.isEmpty(unionList)) {
            return distributionLambdaQueryWrapper.eq(Distribution::getId, -1);
        }
        //获取工会下的店主
        List<String> unionIdList = unionList.stream().map(Union::getId).toList();

        List<UnionMember> unionMemberList = unionMemberClient.getUnionMemberByUnionIdList(unionIdList);

        if (CollectionUtil.isNotEmpty(unionMemberList)) {
            distributionLambdaQueryWrapper.and(q ->
                    q.in(Distribution::getMemberId, unionList.stream().map(Union::getChairmanId).toList()).or()
                            .in(Distribution::getMemberId, unionMemberList.stream().map(UnionMember::getMemberId).toList())
            );
        } else {
            distributionLambdaQueryWrapper.in(Distribution::getMemberId, unionList.stream().map(Union::getChairmanId).toList());
        }
        if (StringUtils.isNotEmpty(distributionVO.getId())) {
            distributionLambdaQueryWrapper.eq(Distribution::getId, distributionVO.getId());
        }
        if (StringUtils.isNotEmpty(distributionVO.getMemberName())) {
            List<Distribution> listByName = this.getListByName(distributionVO.getMemberName());
            if (CollectionUtil.isEmpty(listByName)) {
                distributionLambdaQueryWrapper.eq(Distribution::getId, -1);
            } else {
                distributionLambdaQueryWrapper.in(Distribution::getMemberId, listByName.stream().map(Distribution::getMemberId).collect(Collectors.toList()));
            }
        }
        if (StringUtils.isNotEmpty(distributionVO.getName())) {
            distributionLambdaQueryWrapper.like(Distribution::getName, distributionVO.getName());
        }

        if (StringUtils.isNotEmpty(distributionVO.getFyAccount())) {
            List<User> accountList = userClient.getListByFiledValue("account", distributionVO.getFyAccount());
            if (CollectionUtil.isNotEmpty(accountList)) {
                distributionLambdaQueryWrapper.in(Distribution::getMemberId, accountList.stream().map(User::getId).toList());
            } else {
                distributionLambdaQueryWrapper.eq(Distribution::getId, -1);
            }
        }
        if (StringUtils.isNotEmpty(distributionVO.getFyName())) {
            List<User> fyNameList = userClient.getListByFiledValue("fy_name", distributionVO.getFyName());
            if (CollectionUtil.isNotEmpty(fyNameList)) {
                distributionLambdaQueryWrapper.in(Distribution::getMemberId, fyNameList.stream().map(User::getId).toList());
            } else {
                distributionLambdaQueryWrapper.eq(Distribution::getId, -1);
            }
        }
        if (StringUtils.isNotEmpty(distributionVO.getUnionName())) {
            List<Union> unionNameList = unionClient.getListByFiled("union_name", distributionVO.getUnionName());
            if (CollectionUtil.isEmpty(unionNameList)) {
                distributionLambdaQueryWrapper.eq(Distribution::getId, -1);
            } else {
                List<String> memberIdList = new ArrayList<>(unionNameList.stream().map(Union::getChairmanId).toList());
                List<UnionMember> unionMembers = unionMemberClient.getUnionMemberByUnionIdList(unionNameList.stream().map(Union::getId).toList());
                if (CollectionUtil.isNotEmpty(unionMembers)) {
                    memberIdList.addAll(unionMembers.stream().map(UnionMember::getMemberId).toList());
                }
                distributionLambdaQueryWrapper.in(Distribution::getMemberId, memberIdList);
            }
        }
        distributionLambdaQueryWrapper.eq(Distribution::getDistributionStatus, DistributionStatusEnum.PASS.name());
        distributionLambdaQueryWrapper.orderByDesc(Distribution::getCreateTime);
        return distributionLambdaQueryWrapper;
    }

    /**
     * @param type 1今日，2昨日，3本周，4上周，5本月，6上月，7本季度，8上季度，9今年，10去年
     *
     * @return 店主新增数量 + 店主总数
     */
    @Override
    public NumberOfOwners numberOfOwners(Integer type) {
        return unionMemberClient.numberOfOwners(type);
    }

    /**
     *
     * @param type 1今日，2昨日，3本周，4上周，5本月，6上月，7本季度，8上季度，9今年，10去年
     * @return 总业绩 + 新增业绩
     */
    @Override
    public NumberOfOwners shopOwnersTurnover(Integer type) {
        NumberOfOwners result = new NumberOfOwners();
        result.setTypeNumber(Double.valueOf(0));
        result.setTotalNumber(Double.valueOf(0));
        DistributionVO distributionVO = new DistributionVO();
        distributionVO.setPageNumber(1);
        distributionVO.setPageSize(1000000);
        //构建条件去查询
        LambdaQueryWrapper<Distribution> queryWrapper = this.createQueryWrapper(distributionVO);
        List<Distribution> distributionList = super.list(queryWrapper);
        if (CollectionUtil.isEmpty(distributionList)) {
            return result;
        }
        //根据店主用户id查询直推业绩和佣金收益
        List<String> memberIds = distributionList.stream().map(Distribution::getMemberId).collect(Collectors.toList());
        //查询直推金额和收益佣金
        List<OrderItemViewVO> totalPerformance = orderItemClient.getDistributionFlowPriceAndComissTotalDistribution(memberIds);
        List<OrderItemViewVO> typePerformance = orderItemClient.getDistributionFlowPriceAndComissTotalType(memberIds, type);
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        List<DistributionVO> resultList = new ArrayList<>();
        for (Distribution distribution : distributionList) {
            DistributionVO vo = cn.hutool.core.bean.BeanUtil.toBean(distribution, DistributionVO.class);
            if (CollUtil.isNotEmpty(totalPerformance)) {
                for (OrderItemViewVO orderItemViewVO : totalPerformance) {
                    //赋值总业绩
                    if (orderItemViewVO.getLowerCommissId() != null && orderItemViewVO.getLowerCommissId().equals(vo.getMemberId()) && orderItemViewVO.getLowerCommiss() != null) {
                        vo.setTotalCommiss(vo.getTotalCommiss() + orderItemViewVO.getFlowPrice());
                    }
                }
            }
            if (CollUtil.isNotEmpty(typePerformance)) {
                for (OrderItemViewVO orderItemViewVO : typePerformance) {
                    //赋值类型业绩
                    if (orderItemViewVO.getLowerCommissId() != null && orderItemViewVO.getLowerCommissId().equals(vo.getMemberId()) && orderItemViewVO.getLowerCommiss() != null) {
                        vo.setTypeCommiss(vo.getTypeCommiss() + orderItemViewVO.getFlowPrice());
                    }
                }
            }
            //保留两位
            vo.setTotalCommiss(vo.getTotalCommiss() != null ? Double.parseDouble(decimalFormat.format(vo.getTotalCommiss())) : 0.0);
            vo.setTypeCommiss(vo.getTypeCommiss() != null ? Double.parseDouble(decimalFormat.format(vo.getTypeCommiss())) : 0.0);
            resultList.add(vo);
        }
        result.setTotalNumber(resultList.stream().mapToDouble(DistributionVO::getTotalCommiss).sum());
        result.setTypeNumber(resultList.stream().mapToDouble(DistributionVO::getTypeCommiss).sum());
        return result;
    }

    /**
     * 检查参数
     * @param info
     * @return
     */
    private ResultMessage<Object> checkParams(Distribution info) {
        if (StrUtil.isEmpty(info.getIdNumber())) {
            return ResultUtil.error(400, "身份证号不可为空");
        }
        if (StrUtil.isEmpty(info.getName())) {
            return ResultUtil.error(400, "姓名不可为空");
        }
        if (StrUtil.isEmpty(info.getSettlementBankAccountNum())) {
            return ResultUtil.error(400, "银行账号不可为空");
        }
        if (StrUtil.isEmpty(info.getSettlementBankAccountName())) {
            return ResultUtil.error(400, "开户行名称不可为空");
        }
        return ResultUtil.success();
    }

    /**
     * 修改店主信息
     * @param info
     * @return
     */
    @Override
    public ResultMessage<Object> updateDistributionInfo(Distribution info) {
        //检查参数
        ResultMessage<Object> checkResult = this.checkParams(info);
        if (checkResult.getCode() != 200) {
            return checkResult;
        }
        Distribution disData = baseMapper.selectById(info.getId());
        if (disData == null) {
            return ResultUtil.error(400, "未找到该条店主数据");
        }
        int result = baseMapper.updateById(info);
        return result > 0 ? ResultUtil.success() : ResultUtil.error(400, "修改失败");
    }
}